package ai.taromed.vr.widgets

import ai.taromed.vr.R
import android.content.Context
import android.content.res.Resources
import android.content.res.TypedArray
import android.graphics.*
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.View.OnFocusChangeListener
import kotlin.math.sqrt

class ManualHandleView : View {

    private var defaultBgColor = Color.parseColor("#991B3385")
    private var defaultFocusBgColor = Color.parseColor("#AA1B3385")
    private var defaultForeColor = Color.parseColor("#99dddddd")

    private var bgColor = defaultBgColor
    private var foreColor = defaultForeColor
    private var bgRadius = 0
    private var innerRadius = 0

    // 默认移动大小
    private val DEFAULT_DELTA = 4f

    private val sDensity = Resources.getSystem().displayMetrics.density
    private val sDamping = 2f

    private var bgPaint = Paint()
    private var innerPaint = Paint()

    private var bg_center = Point()
    private var center = Point()

    private var mWidth = 0
    private var mHeight = 0

    private var mVideoRollDx = 0.0f
    private var mVideoRollDy = 0.0f

    constructor(context: Context):super(context)

    constructor(context: Context , attrs: AttributeSet):super(context, attrs){
        init(context, attrs)
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int):super(context, attrs, defStyleAttr) {
        init(context, attrs)
    }

    private fun init(context:Context, attrs:AttributeSet){
        bgPaint.isAntiAlias = true
        innerPaint.isAntiAlias = true
        bgPaint.color = bgColor
        innerPaint.color = foreColor

        val ta: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.ManualHandleView)
        bgColor = ta.getDimensionPixelSize( R.styleable.ManualHandleView_mh_bg_color, defaultBgColor)
        foreColor = ta.getDimensionPixelSize( R.styleable.ManualHandleView_mh_fore_color, defaultForeColor )
        bgRadius = ta.getDimensionPixelSize( R.styleable.ManualHandleView_mh_bg_radius, 0)
        innerRadius = ta.getDimensionPixelSize( R.styleable.ManualHandleView_mh_fore_radius, 0 )


//        isFocusable = true
//        onFocusChangeListener = OnFocusChangeListener { v, hasFocus ->
//            if (hasFocus) {
//                bgColor = defaultFocusBgColor
//                bgPaint.color = defaultFocusBgColor
//                invalidate()
//            } else {
//                bgColor = defaultBgColor
//                bgPaint.color = defaultBgColor
//                invalidate()
//            }
//        }


    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        mWidth = right - left
        mHeight = bottom - top

        bgRadius = mWidth / 2
        innerRadius = bgRadius / 3

        if(center.x == 0){
            center.x = mWidth / 2
        }
        if(center.y == 0){
            center.y = mHeight / 2
        }

        bg_center.x = mWidth / 2
        bg_center.y = mHeight / 2
    }


    override fun onDraw(canvas: Canvas?) {
        canvas?.drawCircle(bg_center.x.toFloat() , bg_center.y.toFloat() , bgRadius.toFloat() , bgPaint )
        canvas?.drawCircle(center.x.toFloat() , center.y.toFloat() , innerRadius.toFloat() , innerPaint )
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if(event == null){
            return false
        }
        var action = event!!.action
        when(action){
            MotionEvent.ACTION_DOWN -> {
                var flag = isInInnerArea(event)
                if(flag){
                    //todo 可以快速震动一下
                    startRollVideo()
                }
                return flag
            }
            MotionEvent.ACTION_MOVE -> {
                whenMove(event)
                mVideoRollDx = (center.x - bg_center.x.toFloat()) / sDensity * sDamping
                mVideoRollDy = (center.y - bg_center.y.toFloat()) / sDensity * sDamping
            }
            MotionEvent.ACTION_UP -> {
                onUp()
                stopRollVideo()
            }
            MotionEvent.ACTION_CANCEL -> {
                stopRollVideo()
                onUp()
            }
        }
        return super.onTouchEvent(event)
    }

    //是否触摸到了内圈
    private fun isInInnerArea(event: MotionEvent):Boolean{
        var x = event.x
        var y = event.y
        var rect = Rect((bgRadius-innerRadius),(bgRadius-innerRadius),(bgRadius+innerRadius),(bgRadius+innerRadius))
        return rect.contains(x.toInt(),y.toInt())
    }

    // 当移动时
    private fun whenMove(event: MotionEvent) {
        var x = event.x
        var y = event.y

        val dx = x - bg_center.x
        val dy = y - bg_center.y
        // 使用平方和公式计算两个圆心之间的距离
        val distance = sqrt((dx * dx + dy * dy).toDouble())

        if (distance <= (bgRadius - innerRadius)) {
            // 如果手指触摸点在外圆内，那么内圆的圆心就是手指触摸点的位置，半径就是手指触摸点到外圆圆心的距离
            center.x = x.toInt()
            center.y = y.toInt()
        } else {
            // 如果手指触摸点在外圆外，那么内圆的圆心就在手指触摸点和外圆圆心之间的线上，距离外圆圆心outerCircleRadius的位置
            val ratio = (bgRadius - innerRadius) / distance
            center.x  = (bg_center.x + ratio * (x - bg_center.x)).toInt()
            center.y = (bg_center.y + ratio *  (y - bg_center.y)).toInt()
        }

        invalidate()
    }

    private var ROLLING_VIDEO_HANDLER_WHAT = 1000
    private var myHandler = MyHandler(Looper.getMainLooper())
    private fun startRollVideo(){
        myHandler.sendEmptyMessage(ROLLING_VIDEO_HANDLER_WHAT)
    }

    private fun stopRollVideo(){
        myHandler.removeCallbacksAndMessages(null)
    }


    // 当手指抬起
    fun onUp(){
        center.x = mWidth / 2
        center.y = mHeight / 2
        invalidate()
    }

    fun reverse(dx: Float, dy: Float){
        center.x = (dx / sDamping * sDensity + bg_center.x.toFloat()).toInt()
        center.y = (dy / sDamping * sDensity + bg_center.y.toFloat()).toInt()
        invalidate()
    }


    private var onManualScrollListener : OnManualScrollListener? = null
    public fun setListener(l : OnManualScrollListener){
        this.onManualScrollListener = l
    }
    interface OnManualScrollListener{
        fun onManualScroll(dx:Float, dy:Float)
    }



    inner class MyHandler : Handler{

        private var ROLLING_VIDEO_HANDLER_DELAY = 30L

        constructor(looper:Looper):super(looper)

        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            var what = msg.what
            when(what){
                ROLLING_VIDEO_HANDLER_WHAT -> {
                    onManualScrollListener?.onManualScroll(mVideoRollDx,mVideoRollDy)
                    sendEmptyMessageDelayed(ROLLING_VIDEO_HANDLER_WHAT , ROLLING_VIDEO_HANDLER_DELAY)
                }
            }
        }
    }


}